{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extracting mover positions\n",
    "\n",
    "<img align=\"right\" src=\"https://anitagraser.github.io/movingpandas/assets/img/movingpandas.png\">\n",
    "\n",
    "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/anitagraser/movingpandas-examples/main?filepath=1-tutorials/3-extracting-mover-positions.ipynb)\n",
    "[![IPYNB](https://img.shields.io/badge/view-ipynb-hotpink)](https://github.com/anitagraser/movingpandas-examples/blob/main/1-tutorials/3-extracting-mover-positions.ipynb)\n",
    "[![HTML](https://img.shields.io/badge/view-html-green)](https://anitagraser.github.io/movingpandas-website/1-tutorials/3-extracting-mover-positions.html)\n",
    "\n",
    "The following examples show how to find a mover's position at a certain time or for a certain time span."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import geopandas as gpd\n",
    "from geopandas import GeoDataFrame, read_file\n",
    "from shapely.geometry import Point, LineString, Polygon\n",
    "from datetime import datetime, timedelta\n",
    "import movingpandas as mpd\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "mpd.show_versions()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's create a basic trajectory:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame([\n",
    "  {'geometry':Point(0,0), 't':datetime(2018,1,1,12,0,0)},\n",
    "  {'geometry':Point(6,0), 't':datetime(2018,1,1,12,6,0)},\n",
    "  {'geometry':Point(6,6), 't':datetime(2018,1,1,12,10,0)},\n",
    "  {'geometry':Point(9,9), 't':datetime(2018,1,1,12,15,0)}\n",
    "]).set_index('t')\n",
    "gdf = GeoDataFrame(df, crs=31256)\n",
    "toy_traj = mpd.Trajectory(gdf, 1)\n",
    "toy_traj"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Extracting a mover's position at a certain time\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(mpd.Trajectory.get_position_at)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When we call this method, the resulting point is directly rendered:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "toy_traj.get_position_at(datetime(2018,1,1,12,6,0), method=\"nearest\")    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see its coordinates, we can look at the print output:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(toy_traj.get_position_at(datetime(2018,1,1,12,6,0), method=\"nearest\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The method parameter describes what the function should do if there is no entry in the trajectory GeoDataFrame for the specified timestamp. \n",
    "\n",
    "For example, there is no entry at 2018-01-01 12:07:00"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "toy_traj.df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = datetime(2018,1,1,12,7,0)\n",
    "print(toy_traj.get_position_at(t, method=\"nearest\"))\n",
    "print(toy_traj.get_position_at(t, method=\"interpolated\"))\n",
    "print(toy_traj.get_position_at(t, method=\"ffill\")) # from the previous row\n",
    "print(toy_traj.get_position_at(t, method=\"bfill\")) # from the following row"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "point = toy_traj.get_position_at(t, method=\"interpolated\")\n",
    "df = pd.DataFrame([{'id': toy_traj.id, 'geometry': point, 't': t}])\n",
    "gdf = GeoDataFrame(df, crs=toy_traj.crs)\n",
    "\n",
    "ax = toy_traj.plot()\n",
    "gdf.plot(ax=ax, color='red', markersize=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ax = toy_traj.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Extracting trajectory segments based on time \n",
    "\n",
    "First, let's extract the trajectory segment for a certain time period:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(mpd.Trajectory.get_segment_between)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "segment = toy_traj.get_segment_between(datetime(2018,1,1,12,6,0), datetime(2018,1,1,12,12,0))\n",
    "print(segment)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ax = toy_traj.plot()\n",
    "segment.plot(ax=ax, color='red', linewidth=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Extracting trajectory segments based on geometry (i.e. clipping)\n",
    "\n",
    "Now, let's extract the trajectory segment that intersects with a given polygon:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xmin, xmax, ymin, ymax = 2, 8, -10, 5\n",
    "polygon = Polygon([(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin), (xmin, ymin)])\n",
    "polygon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "polygon_gdf = GeoDataFrame(pd.DataFrame([{'geometry':polygon, 'id':1}]), crs=31256)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(mpd.Trajectory.clip)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "intersections = toy_traj.clip(polygon)\n",
    "intersections"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ax = toy_traj.plot()\n",
    "polygon_gdf.plot(ax=ax, color='lightgray')\n",
    "intersections.plot(ax=ax, color='red', linewidth=5, capstyle='round')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
